import * as THREE from 'three'

/**
 * GPU拾取 - 简化版本，用于节点选择
 */
export class GPUPicking {
  constructor(renderer, scene, camera) {
    this.renderer = renderer
    this.scene = scene
    this.camera = camera
    
    this.pickingTexture = null
    this.pickingMaterial = null
    this.pickingScene = null
    
    this.mouse = new THREE.Vector2()
    this.raycaster = new THREE.Raycaster()
  }

  /**
   * 初始化
   */
  init() {
    // 创建拾取纹理
    this.pickingTexture = new THREE.WebGLRenderTarget(
      this.renderer.domElement.width,
      this.renderer.domElement.height
    )
    
    // 创建拾取材质
    this.pickingMaterial = new THREE.ShaderMaterial({
      vertexShader: `
        attribute float nodeId;
        varying vec3 vColor;
        
        void main() {
          // 将节点ID编码为颜色
          float id = nodeId;
          vColor.r = mod(id, 256.0) / 255.0;
          vColor.g = mod(floor(id / 256.0), 256.0) / 255.0;
          vColor.b = mod(floor(id / 65536.0), 256.0) / 255.0;
          
          vec4 mvPosition = modelViewMatrix * vec4(position, 1.0);
          gl_PointSize = 20.0 * (300.0 / -mvPosition.z);
          gl_Position = projectionMatrix * mvPosition;
        }
      `,
      fragmentShader: `
        varying vec3 vColor;
        
        void main() {
          float dist = distance(gl_PointCoord, vec2(0.5));
          if (dist > 0.5) discard;
          gl_FragColor = vec4(vColor, 1.0);
        }
      `
    })
    
    this.pickingScene = new THREE.Scene()
  }

  /**
   * 添加可拾取对象
   */
  addPickableObject(object) {
    if (this.pickingScene) {
      const pickingObject = object.clone()
      pickingObject.material = this.pickingMaterial
      this.pickingScene.add(pickingObject)
    }
  }

  /**
   * 拾取节点
   */
  pick(x, y) {
    if (!this.pickingTexture || !this.pickingScene) return null
    
    // 更新鼠标位置
    this.mouse.x = (x / this.renderer.domElement.width) * 2 - 1
    this.mouse.y = -(y / this.renderer.domElement.height) * 2 + 1
    
    // 渲染到拾取纹理
    this.renderer.setRenderTarget(this.pickingTexture)
    this.renderer.render(this.pickingScene, this.camera)
    
    // 读取像素
    const pixelBuffer = new Uint8Array(4)
    this.renderer.readRenderTargetPixels(
      this.pickingTexture,
      x, this.renderer.domElement.height - y,
      1, 1,
      pixelBuffer
    )
    
    // 恢复默认渲染目标
    this.renderer.setRenderTarget(null)
    
    // 解码节点ID
    const id = pixelBuffer[0] + (pixelBuffer[1] << 8) + (pixelBuffer[2] << 16)
    
    return id > 0 ? id - 1 : null // 返回节点索引
  }

  /**
   * 射线拾取（备用方法）
   */
  raycastPick(x, y, objects) {
    this.mouse.x = (x / this.renderer.domElement.width) * 2 - 1
    this.mouse.y = -(y / this.renderer.domElement.height) * 2 + 1
    
    this.raycaster.setFromCamera(this.mouse, this.camera)
    
    const intersects = this.raycaster.intersectObjects(objects)
    return intersects.length > 0 ? intersects[0] : null
  }

  /**
   * 销毁资源
   */
  dispose() {
    if (this.pickingTexture) {
      this.pickingTexture.dispose()
    }
    if (this.pickingMaterial) {
      this.pickingMaterial.dispose()
    }
  }
}
